
package w83b.w83bUtilidadesComunes;

import java.io.Serializable;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;

import javax.xml.soap.MessageFactory;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;


import w83b.xml.W83bXmlDocument;
import w83b.xml.W83bXmlElement;
import w83b.xml.exception.W83bXmlException;
import weblogic.webservice.core.soap.SOAPElementImpl;
import weblogic.webservice.core.soap.SOAPTextElement;

public class W83bWebServiceCall implements Serializable {
	
	private static final long serialVersionUID=0;
	
	private static final String sParameterName = "strXML";

	private String sURL = "";

	private String paramValues = "";

	private String sMethod = "";

	public W83bWebServiceCall(String sURL, String sMethod, String serviceId,
			String procedureID, String applicationID, String sesionToken,
			TreeMap campoValor) {
		this.sURL = sURL;
		this.paramValues = getXml(serviceId, procedureID, applicationID,
				sesionToken, campoValor);
		this.sMethod = sMethod;
	}

	public W83bWebServiceCall(String sURL, String sMethod) {
		this.sURL = sURL;
		this.sMethod = sMethod;
	}

	public String invoke() {
		String rtdo = "";
		try {
			MessageFactory mfactory = MessageFactory.newInstance();
			SOAPMessage message = mfactory.createMessage();
			SOAPPart soapPart = message.getSOAPPart();
			SOAPEnvelope envelope = soapPart.getEnvelope();
			SOAPBody body = envelope.getBody();

			Name name = envelope.createName(this.sMethod, "",
					"http://www.openuri.org/");
			SOAPBodyElement element = body.addBodyElement(name);

			SOAPElement param = element.addChildElement(envelope
					.createName(sParameterName));
			param.addTextNode(this.paramValues);

			SOAPConnectionFactory factory = SOAPConnectionFactory.newInstance();
			SOAPConnection con = factory.createConnection();
			SOAPMessage response = con.call(message, this.sURL);

			rtdo = getResultado(response);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return rtdo;
	}

	private static String getXml(String serviceId, String procedureID,
			String applicationID, String sesionToken, TreeMap campoValor) {
		StringBuffer resultado =new StringBuffer(W83bClsConstantes.CUARENTA);
		
			resultado.append("<servicerequest>").append("<meta>").append("<id_servicio>").append(serviceId).append("</id_servicio>");
		if (procedureID != null)
			{resultado.append("<procedureID>").append(procedureID).append("</procedureID>");}
		if (applicationID != null)
			{resultado.append("<applicationID>").append(applicationID).append("</applicationID>");}
		resultado.append("<tkn_seguridad>").append(sesionToken).append("</tkn_seguridad>").append("</meta>").append("<data>").append("<parametros>");

		Iterator iterator = campoValor.entrySet().iterator();
		while (iterator.hasNext()) {
			Map.Entry entry = (Map.Entry) iterator.next();
			String campo = (String) entry.getKey();
			String valor = (String) entry.getValue();
			resultado.append("<parametro nombre=\"").append(campo).append("\" valor=\"java.lang.String\">").append(valor).append("</parametro>");
		}

		resultado.append("</parametros>").append("</data>").append("</servicerequest>");
		return resultado.toString();
	}

	private static SOAPBodyElement getSOAPBodyElement(SOAPMessage response)
			throws SOAPException {
		SOAPBodyElement rtdo = null;
		Iterator iterator = response.getSOAPPart().getEnvelope().getBody()
				.getChildElements();

		while (iterator.hasNext()) {
			Object oUndefined = iterator.next();
			if (oUndefined instanceof SOAPBodyElement) {
				rtdo = (SOAPBodyElement) oUndefined;
				break;
			}
		}
		return rtdo;
	}

	public static String getResultado(SOAPMessage response)
			throws SOAPException {
		StringBuffer rtdo = new StringBuffer("");
		StringBuffer masRtdo = new StringBuffer("");
		SOAPBodyElement soapBodyElement = getSOAPBodyElement(response);
		String responseElementName = soapBodyElement.getElementName()
				.toString();
		if (!responseElementName.equalsIgnoreCase("SOAP-ENV:Fault")) {
			String resultElementName = responseElementName.replaceAll(
					"Response$", "Result");
			Iterator iterator = soapBodyElement.getChildElements();

			while (iterator.hasNext()) {
				SOAPElement element = (SOAPElement) iterator.next();
				String elementName = element.getElementName().toString();
				if (elementName.equals(resultElementName)) {
					// el element es el elemento resultado.
					rtdo.append(element.getValue());
					break;
				}
			}
		} else {
			rtdo.append("Fallo:");
			//Recoger el fallo que viene dentro de la etiqueta faultstring y
			// mandarlo en rtdo
			Iterator iterator = soapBodyElement.getChildElements();

			while (iterator.hasNext()) {

				Object objeto = iterator.next();
				Class clase = objeto.getClass();
				String nombreClase = clase.toString();
				if (("class weblogic.webservice.core.soap.SOAPElementImpl").equals(nombreClase)) {
					SOAPElementImpl element = (SOAPElementImpl) objeto;
					String elementName = element.getElementName().toString();
					if (("faultstring").equals(elementName)) {
						Iterator hijos = element.getChildren();
						while (hijos.hasNext()) {
							Object objetoHijo = hijos.next();
							SOAPTextElement texto = (SOAPTextElement) objetoHijo;
							String texto1 = texto.toString();
							if (texto1.indexOf("</>") != -1)
							{	texto1 = texto1.substring(0, texto1
										.indexOf("</>"));}
							masRtdo.append(texto1);
						}
						rtdo.append(masRtdo);
						break;
					}
				}
			}
		}
		return rtdo.toString();
	}

	//si la respuesta es mala, devuelvo la descripción de error. Siempre
	// empieza por ERROR para poder parsearla
	public String[] analizarRespuesta(String respuesta) {

		String[] rtdo = new String[2];

		try {
			W83bXmlDocument docXmlPresentacion = new W83bXmlDocument();
			docXmlPresentacion.createFromUtf8StringText(respuesta);
			W83bXmlElement root = docXmlPresentacion.getRootElement();

			W83bXmlElement returncode = root.getXmlElement("meta/returncode");
			if (returncode != null) {
				String codigoresp = returncode.getValue();
				if (("00000").equals(codigoresp)) {
					//traceid. Lo necesito para los documentos
					W83bXmlElement traceidXml = root
							.getXmlElement("meta/traceid");
					if (traceidXml != null) {
						rtdo[0] = traceidXml.getValue();
					} else
						{rtdo[0] = "";}
					//cojo la respuesta
					W83bXmlElement respuestaXml = root
							.getXmlElement("data/respuesta");
					if (respuestaXml != null) {
						rtdo[1] = respuestaXml.getValue();
					} else {
						//miro si viene parameters
						W83bXmlElement parametersXml = root
								.getXmlElement("data/parameters");
						if (parametersXml != null) {
							rtdo[1] = parametersXml.getStringText(true);
						}
					}
				} else {
					W83bXmlElement errorDescription = root
							.getXmlElement("meta/errordescription");
					if (errorDescription != null)
						{rtdo[1] = "ERROR: " + errorDescription.getValue();}
				}
			}
		} catch (W83bXmlException e) {
			e.printStackTrace();
		}
		return rtdo;
	}

	// Método para invocar al webService a partir del xml que devuelve el CP
	/*
	 * public String invokeXmlCP (String sXml, String procedureID, String
	 * applicationID, String sesionToken, HashMap dataHashMapValoresFormulario){
	 * String serviceId = ""; TreeMap campoValor = new TreeMap(); String
	 * rtdo=""; try{ W83bXmlDocument docXmlPresentacion = new W83bXmlDocument();
	 * docXmlPresentacion.createFromUtf8StringText(sXml); W83bXmlElement root =
	 * docXmlPresentacion.getRootElement(); W83bXmlElement elemento;
	 * 
	 * W83bXmlElement serviceIdElement = root.getXmlElement("serviceId");
	 * if(serviceIdElement!=null) serviceId=serviceIdElement.getValue();
	 * 
	 * W83bXmlElements
	 * camposFormularioElement=R02kUtilXml.getElements(root,"camposFormulario");
	 * if(camposFormularioElement!=null){ for(int i=1;i
	 * <camposFormularioElement.getCount()+1;i++){ String nombre=""; String
	 * paramSV=""; elemento=camposFormularioElement.getItem(i); W83bXmlElement
	 * nombreElement = elemento.getXmlElement("campoFormulario/nombre");
	 * W83bXmlElement paramSVElement =
	 * elemento.getXmlElement("campoFormulario/paramSV");
	 * if(nombreElement!=null) nombre=nombreElement.getValue();
	 * if(paramSVElement!=null) paramSV=paramSVElement.getValue();
	 * 
	 * //Buscar el valor del campo nombre en el formulario Iterator it =
	 * dataHashMapValoresFormulario.entrySet().iterator(); boolean
	 * encontrado=false; String valorCampoFormulario=""; while(it.hasNext() &&
	 * !encontrado){ Map.Entry e = (Map.Entry)it.next();
	 * if(nombre.equals(e.getKey())){ String[] valorFormulario =
	 * (String[])e.getValue(); valorCampoFormulario = valorFormulario[0];
	 * encontrado = true; } } campoValor.put(paramSV, valorCampoFormulario); } }
	 * this.paramValues = getXml(serviceId, procedureID, applicationID,
	 * sesionToken, campoValor); rtdo= this.invoke(); }catch (Exception e) {
	 * e.printStackTrace(); } return rtdo; }
	 */

}